<?php

namespace App\Services\Base;

use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class CacheService
{

    public static function get($key, $db = '')
    {
        try {
            $records = Redis::connection($db)->get($key);
            $decoded = json_decode($records, true);
            return $decoded ? $decoded : $records;
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }


    public static function set($key, $value, $expiration = 0, $db = '')
    {
        if (!$value) {
            return null;
        }
        $value = json_encode($value);
        try {
            if ($expiration) {
                return Redis::connection($db)->setex($key, $expiration, $value);
            } else {
                return Redis::connection($db)->set($key, $value);
            }

        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }


    public static function serialize($key, $value, $expiration = 0, $db = '')
    {
        if (!$value) {
            return null;
        }

        $value = serialize($value);
        try {
            if ($expiration) {
                return Redis::connection($db)->setex($key, $expiration, $value);
            } else {
                return Redis::connection($db)->set($key, $value);
            }
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function unserialize($key, $db = '')
    {
        try {
            $records = Redis::connection($db)->get($key);
            return !empty($records) ? unserialize($records) : "";
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function expireKey($key, $time = 60, $db = '')
    {
        try {
            return Redis::connection($db)->EXPIRE($key, $time);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }


    public static function del($key, $db = '')
    {
        try {
            return Redis::connection($db)->del($key);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }


    public static function inc($key, $step = 1, $db = '')
    {
        try {
            return Redis::connection($db)->incrBy($key, $step);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function decr($key, $step = 1, $db = '')
    {
        try {
            return Redis::connection($db)->DECRBY($key, $step);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function allKeysByKey($key, $db = '')
    {
        try {
            return Redis::connection($db)->keys("*" . $key . "*");
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function allKeysRight($key, $db = '')
    {
        try {
            return Redis::connection($db)->keys($key . "*");
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function zAdd($key, $value, $score = 1, $db = '')
    {
        try {
            return Redis::connection($db)->zAdd($key, $score, $value);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function zScore($key, $value, $db = '')
    {
        try {
            return Redis::connection($db)->ZSCORE($key, $value);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function zRange($key, $start = 0, $end = -1, $withScores = false, $db = '')
    {
        try {
            return Redis::connection($db)->zRange($key, $start, $end, ['withscores' => $withScores]);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function zRevRange($key, $start = 0, $end = -1, $withScores = false, $db = '')
    {
        try {
            return Redis::connection($db)->zRevRange($key, $start, $end, ['withscores' => $withScores]);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function zRangeByScore($key, $start = 0, $end = '+inf', $db = '', $withScores = false)
    {
        try {
            return Redis::connection($db)->zRangeByScore($key, $start, $end, ['withscores' => $withScores]);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function zRemRangeByScore($key, $start = 0, $end = '+inf', $db = '')
    {
        try {
            return Redis::connection($db)->zRemRangeByScore($key, $start, $end);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }


    public static function zRem($key, $member, $db = '')
    {
        try {
            return Redis::connection($db)->ZREM($key, $member);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function lPush($key, $value, $db = '')
    {
        try {
            return Redis::connection($db)->LPUSH($key, $value);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function rPush($key, $value, $db = '')
    {
        try {
            return Redis::connection($db)->RPUSH($key, $value);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function lPop($key, $db = '')
    {
        try {
            return Redis::connection($db)->LPOP($key);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function rPop($key, $db = '')
    {
        try {
            return Redis::connection($db)->RPOP($key);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function lRange($key, $db = '')
    {
        try {
            return Redis::connection($db)->LRANGE($key, 0, -1);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }


    public static function sAdd($key, $value, $db = '')
    {
        try {
            if (is_array($value)) {
                return Redis::connection($db)->SAdd($key, ...$value);
            } else {
                return Redis::connection($db)->SAdd($key, $value);
            }

        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function sRandMember($key, $value, $db = '')
    {
        try {
            return Redis::connection($db)->SRANDMEMBER($key, $value);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function sIsMember($key, $value, $db = '')
    {
        try {
            return Redis::connection($db)->SISMEMBER($key, $value);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }


    public static function sMembers($key, $db = '')
    {
        try {
            return Redis::connection($db)->SMEMBERS($key);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function sRem($key, $value, $db = '')
    {
        var_dump([$key, $value]);
        try {
            return Redis::connection($db)->SREM($key, $value);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function sCard($key, $db = '')
    {
        try {
            return Redis::connection($db)->SCARD($key);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }


    public static function exists($key, $db = '')
    {
        try {
            return Redis::connection($db)->EXISTS($key);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function setNx($key, $value, $db = '')
    {
        try {
            $value = (int)$value;
            if ($value < 1) {
                $value = 300;
            }
            $value = time() + $value;
            return Redis::connection($db)->SETNX($key, $value);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function lLen($key, $db = '')
    {
        try {
            return Redis::connection($db)->LLEN($key);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function hGetAll($key, $db = '')
    {
        try {
            return Redis::connection($db)->HGETALL($key);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function hSet($key, $field, $value, $encode = false, $db = '')
    {
        try {
            if ($encode) {
                return Redis::connection($db)->HSET($key, $field, json_encode($value, JSON_UNESCAPED_UNICODE));
            } else {
                return Redis::connection($db)->HSET($key, $field, $value);
            }

        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function hGet($key, $field, $encode = false, $db = '')
    {
        try {
            $ret = Redis::connection($db)->HGET($key, $field);
            if ($encode) {
                return json_decode($ret, true);
            } else {
                return $ret;
            }
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    public static function hDel($key, $field, $db = '')
    {
        try {
            return Redis::connection($db)->HDEL($key, $field);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }

    /**
     * @param $key
     * @param string $db
     * @return string 0=>none (key不存在) 1=>string (字符串) 2=>list (列表) 3=>set (集合) 4=>zset (有序集) 5=>hash (哈希表)
     */
    public static function type($key, $db = '')
    {
        try {
            return Redis::connection($db)->TYPE($key);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return R_REDIS_ERROR;
        }
    }


    public static function getSet($key, $field, $db = '')
    {
        try {
            return Redis::connection($db)->GETSET($key, $field);
        } catch (\Throwable $e) {
            Log::error("redis异常(" . $key . ")" . $e->getLine() . "-" . $e->getMessage());
            return "";
        }
    }
}
